#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File    : interface.window.py
# @Note    : GUI 主窗口界面

import os
import time
from shutil import move

import matplotlib.pyplot as plt
import numpy as np
import psutil
import pythoncom

from winreg import OpenKey, QueryValueEx, HKEY_CURRENT_USER

import ctypes
import win32con
import threading

from win32process import SuspendThread, ResumeThread
from PyQt5.QtCore import QThread, QTimer, Qt, pyqtSignal
from PyQt5.QtGui import QIcon, QPixmap, QTextCursor
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QApplication, QMessageBox
from PyQt5.uic import loadUiType

import process.process
from interface import version, contact, waiting
from simulation import simulation


class MyThread(QThread):
    handle = -1
    stop_flag = False
    save_signal = pyqtSignal(bool)

    def __init__(self):
        super().__init__()
        self.sim = simulation.Sim()
        self.para = []

    def run(self):
        try:
            self.handle = ctypes.windll.kernel32.OpenThread(win32con.PROCESS_ALL_ACCESS, False,
                                                            int(QThread.currentThreadId()))
        except (IndexError, Exception):
            pass
        if not self.stop_flag:
            # 初始化资源
            pythoncom.CoInitialize()
            self.sim.run(self.para[0], self.para[1], self.para[2])
            save = True
            print("仿真训练结束")
            self.save_signal.emit(True)
        else:
            pass


def get_desktop_path():
    key = OpenKey(HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders')
    return QueryValueEx(key, "Desktop")[0]


def backup_model(source, target):
    # 移动所有模型文件到备份文件夹下
    for root, dirs, files in os.walk(source):
        if len(files) > 0:
            # 获取系统时间
            now = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))
            # 创建新备份子文件夹
            path = target + now + '/'
            if os.path.exists(path):
                pass
            else:
                os.makedirs(path)
            # 移动文件
            for file in files:
                move(os.path.join(root, file), path)


# 生成配时方案
def create_plans(timming):
    # 配时范围
    green_low = timming[0]
    green_high = timming[1]
    green_interval = timming[2]
    cycle_time = timming[3]
    loss_time = timming[4]
    amber_time = timming[5]
    clearing_time = timming[6]
    plans = []
    try:
        with open("./model/timming_plans.txt", "a+") as f:
            f.truncate(0)
    except (IndexError, Exception):
        pass
    for a in range(green_low, green_high + 1, green_interval):
        for b in range(green_low, green_high + 1, green_interval):
            for c in range(green_low, green_high + 1, green_interval):
                for d in range(green_low, green_high + 1, green_interval):
                    if (a + b + c + d) == (cycle_time - loss_time):
                        plan = [cycle_time, amber_time, clearing_time, [a, b, c, d]]
                        plans.append(plan)
                        with open("./model/timming_plans.txt", "a+") as f:
                            line = "%s\n" % (str(plan))
                            f.write(line)
    return plans


ui, _ = loadUiType("./resource/ui/window.ui")


# 主窗口界面
class MainWindow(QMainWindow, ui):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.resize(1366, 700)
        self.setWindowFlags(Qt.WindowMinimizeButtonHint)
        self.setWindowTitle("集成Vissim-Python的信控交叉口配时仿真系统")
        self.setWindowIcon(QIcon("./resource/icon/app.png"))
        # 隐藏tab标签
        self.tabWidget.tabBar().setVisible(False)
        # 类属性
        self.program_path = r"E:\Program Files (x86)\PTV_Vision\VISSIM430\Exe\vissim.exe"
        self.net_path = os.getcwd().replace("\\", "/") + "/resource/vissim/3.inp"
        self.flow_path = os.getcwd().replace("\\", "/") + "/resource/data/vehicle_inputs.txt"
        self.save_path = os.getcwd().replace("\\", "/") + "/resource/save/"
        self.vehicle = []
        self.num = 0
        self.simulation = [999999, 0, 1, 1, 42, False, False]
        self.timming = [26, 32, 2, 130, 20, 3, [2, 2, 2, 2]]
        self.plans = []
        # 实例化类
        self.versionDialog = version.versionDialog()
        self.contactDialog = contact.contactDialog()
        self.waiting = waiting.wait_start()
        # 让图片自适应label大小
        self.label_net.setScaledContents(True)
        self.label_alg.setScaledContents(True)
        self.label_sim.setScaledContents(True)
        self.label_eval.setScaledContents(True)
        # 设置图标
        self.label_net.setPixmap(QPixmap("./resource/icon/net.png"))
        self.label_alg.setPixmap(QPixmap("./resource/icon/algorithm.png"))
        self.label_sim.setPixmap(QPixmap("./resource/icon/simulation.png"))
        self.label_eval.setPixmap(QPixmap("./resource/icon/evaluate.png"))
        # 主界面界面切换槽函数
        self.pushButton1.clicked.connect(self.switch_to_net_panel)
        self.pushButton2.clicked.connect(self.switch_to_algorithm_panel)
        self.pushButton3.clicked.connect(self.switch_to_simulation_panel)
        self.pushButton4.clicked.connect(self.switch_to_evaluate_panel)
        # 菜单栏触发信号
        self.action_load.triggered.connect(self.load_net_file)
        self.action_save.triggered.connect(self.save_net_file)
        self.action_exit.triggered.connect(self.quit_program)
        self.action_local.triggered.connect(self.open_local_help_document)
        self.action_version.triggered.connect(self.versionDialog.show)
        self.action_contact.triggered.connect(self.contactDialog.show)
        # 路网界面按钮槽连接
        self.pushButton_load.clicked.connect(self.load_net_file)
        self.pushButton_parse.clicked.connect(self.parse_net_file)
        self.pushButton_save.clicked.connect(self.save_net_file)
        # 仿真界面按钮槽连接
        self.pushButton_program_path.clicked.connect(self.load_program_path)
        self.pushButton_net_path.clicked.connect(self.load_net_path)
        self.pushButton_flow_path.clicked.connect(self.load_flow_path)
        self.pushButton_save_path.clicked.connect(self.load_save_path)
        self.pushButton_simulation_run.clicked.connect(self.run_simulation)
        self.pushButton_simulation_stop_continue.clicked.connect(self.stop_continue_simulation)
        self.pushButton_simulation_quit.clicked.connect(self.quit_simulation)
        # 初始化仿真设置
        self.lineEdit_sim_path.setText(self.program_path)
        self.lineEdit_net_path.setText(self.net_path)
        self.lineEdit_flow_path.setText(self.flow_path)
        self.lineEdit_save_path.setText(self.save_path)
        # 样式表切换
        self.QSS_sheet = [
            "QPushButton{border:none;color:black;font-size:11;border-radius:10px;padding-left:5px;padding-right:10px;\
            text-align:middle;background:LightGray;background-color:#FF69B4;}"
            "QPushButton:hover{color:white;border:1px solid #F3F3F5;border-radius:10px;background:#00FF00;}"
            "QPushButton:pressed{color:red;border:3px solid #4169E1;border-radius:10px;background:#00FF00;}",
            "QPushButton{border:none;color:black;font-size:11;border-radius:10px;padding-left:5px;padding-right:10px;\
            text-align:middle;background:LightGray;background-color:#808080;}"
            "QPushButton:hover{color:white;border:1px solid #F3F3F5;border-radius:10px;background:#00FF00;}"
            "QPushButton:pressed{color:red;border:3px solid #4169E1;border-radius:10px;background:#00FF00;}",
        ]
        # 按钮状态
        self.pushButton_simulation_quit.setEnabled(False)
        self.pushButton_simulation_quit.setStyleSheet(self.QSS_sheet[1])
        self.pushButton_simulation_stop_continue.setEnabled(False)
        self.pushButton_simulation_stop_continue.setStyleSheet(self.QSS_sheet[1])
        self.pushButton_simulation_stop_continue.setText("停止仿真")
        # 注册子线程服务
        self.sim_task = MyThread()
        self.sim = self.sim_task.sim
        self.sim_task.finished.connect(self.sim_task.deleteLater)
        self.sim_task.save_signal.connect(self.save_simulation_data)
        # 连接自定义信号
        self.sim.SimInfoEmit.connect(self.update_simulation_textBrowser)
        self.sim.EvaInfoEmit.connect(self.update_evaluate_textBrowser)
        self.sim.RateProgressInfoEmit.connect(self.update_progressBar)
        # 实例化定时器
        self.system_memory = QTimer()
        self.system_memory.timeout.connect(self.imshow_system_memory)
        self.system_memory.start(10*1000)
        # 初始进度条信息
        self.progressBar.setValue(0)
        # 显示内存信息
        self.imshow_system_memory()
        # 默认显示路网界面
        self.switch_to_net_panel()

    # 显示系统内存信息
    def imshow_system_memory(self):
        mem = psutil.virtual_memory()
        # 系统总计内存
        total_memory = float(mem.total) / 1024 / 1024 / 1024
        # 系统已经使用内存
        use_memory = float(mem.used) / 1024 / 1024 / 1024
        use_percent = use_memory / total_memory * 100
        use_percent = round(use_percent, 2)
        info = '系统已用内存：%3d%%, %.2f GB / %.2f GB\n' % (use_percent, use_memory, total_memory)
        self.label_system_memory.setText(info)
        # with open('./model/system_memoory.txt', 'a+') as f:
        #     f.write(info)

    # 退出程序
    def quit_program(self):
        reply = QMessageBox.question(self, '提示', "是否要退出程序？", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.close()
        else:
            self.showMinimized()

    # 打开本地帮助文档
    def open_local_help_document(self):
        path = os.getcwd() + r"/resource/help/user manual.chm"
        if os.path.exists(path):
            os.startfile(path)
        else:
            QMessageBox.warning(self, "提示", "当前目录下帮助文档不存在")

    # 切换到路网界面
    def switch_to_net_panel(self):
        self.tabWidget.setCurrentIndex(0)
        self.statusBar().showMessage("路网界面")

    # 切换到算法界面
    def switch_to_algorithm_panel(self):
        self.tabWidget.setCurrentIndex(1)
        self.statusBar().showMessage("算法界面")

    # 切换到仿真界面·
    def switch_to_simulation_panel(self):
        self.tabWidget.setCurrentIndex(2)
        self.statusBar().showMessage("仿真界面")

    # 切换到评价界面
    def switch_to_evaluate_panel(self):
        self.tabWidget.setCurrentIndex(3)
        self.statusBar().showMessage("评估界面")

    """路网界面"""

    # 解析路网文件
    def parse_net_file(self):
        try:
            with open(self.net_path, "r") as f:
                content = f.readlines()
            self.textBrowser_net_info.clear()
            for i in range(len(content)):
                self.textBrowser_net_info.append(content[i])
            self.textBrowser_net_info.moveCursor(QTextCursor.Start)
            QMessageBox.information(self, "提示", "解析路网文件成功")
        except (IndexError, Exception):
            QMessageBox.warning(self, "提示", "解析路网文件失败")

    # 保存路网文件
    def save_net_file(self):
        reply = QFileDialog.getSaveFileName(self, '道路仿真路网文件', './resource/', "文本(*.inp)")
        try:
            if reply[0]:
                with open(reply[0], "w") as f:
                    f.write(self.textBrowser_net_info.toPlainText())
                QMessageBox.information(self, "提示", "保存路网文件成功")
            else:
                QMessageBox.warning(self, "提示", "请选择正确的路径并确认")
        except (IndexError, Exception):
            QMessageBox.warning(self, "提示", "保存路网文件失败")

    # 加载路网文件
    def load_net_file(self):
        reply = QFileDialog.getOpenFileName(self, "道路仿真路网文件", "./resource/", "(*.inp)")
        try:
            if reply[0]:
                self.net_path = reply[0]
                QMessageBox.information(self, "提示", "加载路网文件成功")
            else:
                QMessageBox.warning(self, "提示", "请选择正确的路径并确认")
        except (IndexError, Exception):
            QMessageBox.warning(self, "提示", "加载路网文件失败")

    """算法界面"""

    # 加载仿真软件路径
    def load_program_path(self):
        reply = QFileDialog.getOpenFileName(self, "加载vissim启动文件", get_desktop_path(), "(*.exe *.lnk)")
        try:
            if reply[0]:
                self.program_path = reply[0]
                self.lineEdit_sim_path.setText(self.program_path)
                QMessageBox.information(self, "提示", "vissim启动文件路径加载成功")
            else:
                QMessageBox.information(self, "提示", "vissim启动文件路径加载失败")
        except (IndexError, Exception):
            QMessageBox.information(self, "提示", "vissim启动文件路径加载失败")

    # 加载路网文件路径
    def load_net_path(self):
        reply = QFileDialog.getOpenFileName(self, "道路仿真路网文件", "./", "(*.inp *.ini)")
        try:
            if reply[0]:
                self.net_path = reply[0]
                self.lineEdit_net_path.setText(self.net_path)
                QMessageBox.information(self, "提示", "道路仿真路网文件路径加载成功")
            else:
                QMessageBox.information(self, "提示", "道路仿真路网文件路径加载失败")
        except (IndexError, Exception):
            QMessageBox.information(self, "提示", "道路仿真路网文件路径加载失败")

    # 加载交通流量文件路径
    def load_flow_path(self):
        reply = QFileDialog.getOpenFileName(self, "交通流量文件", "./", "(*.txt *.xlsx *.xls)")
        try:
            if reply[0]:
                self.flow_path = reply[0]
                self.lineEdit_flow_path.setText(self.flow_path)
                QMessageBox.information(self, "提示", "交通流量文件路径加载成功")
            else:
                QMessageBox.information(self, "提示", "交通流量文件路径加载失败")
        except (IndexError, Exception):
            QMessageBox.information(self, "提示", "交通流量文件路径加载失败")

    # 加载评价保存路径
    def load_save_path(self):
        reply = QFileDialog.getExistingDirectory(self, "仿真结果保存路径", "./")
        try:
            if reply[0]:
                self.save_path = reply
                self.lineEdit_save_path.setText(self.save_path)
                QMessageBox.information(self, "提示", "仿真结果保存路径加载成功")
            else:
                QMessageBox.information(self, "提示", "仿真结果保存路径加载失败")
        except (IndexError, Exception):
            QMessageBox.information(self, "提示", "仿真结果保存路径加载失败")

    """仿真信息界面"""

    # 加载网络模型参数设置
    def load_network_setting(self):
        simulation.ALGORITHM = self.comboBox_algorithm.currentText()
        simulation.LOSS = self.comboBox_loss.currentText()
        simulation.OPTIM = self.comboBox_optim.currentText()
        simulation.ACTIVATE = self.comboBox_activate.currentText()

    # 加载仿真环境参数设置
    def load_environment_setting(self):
        period = int(self.lineEdit_Sim_Period.text())
        speed = int(self.lineEdit_Sim_speed.text())
        resolution = int(self.lineEdit_Sim_resolution.text())
        control_freq = int(self.lineEdit_Control_Freq.text())
        seed = int(self.lineEdit_Random_Seed.text())
        if self.radioButton_hidden_flow.isChecked():
            visualization = False
        else:
            visualization = True
        if self.radioButton_3D_mode.isChecked():
            mode = True
        else:
            mode = False
        self.simulation = [period, speed, resolution, control_freq, seed, visualization, mode]

    # 加载仿真算法参数设置
    def load_algorithm_setting(self):
        simulation.LR = float(self.lineEdit_LR.text())
        simulation.EPSILON = float(self.lineEdit_EPSILON.text())
        simulation.EPSILON_MAX = float(self.lineEdit_EPSILON.text())
        simulation.GAMMA = float(self.lineEdit_GAMMA.text())
        simulation.EPISODE = int(self.lineEdit_EPISODE.text())
        simulation.MEMORY_CAPACITY = int(self.lineEdit_MEMORY_CAPACITY.text())
        simulation.BATCH_SIZE = int(self.lineEdit_BATCH_SIZE.text())
        simulation.UPDATE_STEP = int(self.lineEdit_UPDATE_STEP.text())
        simulation.TEST_FREQUENCY = float(self.lineEdit_TEST_FREQUENCY.text())
        simulation.CONVERGENCE_UP = int(self.lineEdit_CONVERGENCE_UP.text())
        simulation.CONVERGENCE_LOW = int(self.lineEdit_CONVERGENCE_LOW.text())
        simulation.ZEROREWARD = int(self.lineEdit_ZEROREWARD.text())
        simulation.CONVERGENCE = int(self.lineEdit_CONVERGENCE.text())

    # 加载仿真配时参数设置
    def load_timing_setting(self):
        cycle_time = int(self.lineEdit_cycle_time.text())
        loss_time = int(self.lineEdit_loss_time.text())
        green_short = int(self.lineEdit_green_short.text())
        green_long = int(self.lineEdit_green_long.text())
        clear_time = list(map(lambda x: int(x), str(self.lineEdit_clear_time.text()).split(',')))
        yellow = int(self.lineEdit_yellow.text())
        self.timming = [green_short, green_long, 2, cycle_time, loss_time, yellow, clear_time]

    # 加载车流量
    def load_traffic_flow(self, elapsed_time):
        while True:
            if elapsed_time < self.vehicle[self.num][1]:
                break
            else:
                self.num += 1
        return self.vehicle[self.num][2:]

    # 加载车流量配置文件
    def load_traffic_flow_file(self):
        with open(self.flow_path, "r") as f:
            lines = f.readlines()
        self.vehicle = []
        self.num = 0
        for i in range(1, len(lines)):
            self.vehicle.append(list(map(int, lines[i].split())))

    # 显示提示信息
    def show_hint_information(self):
        self.textBrowser_sim_info.clear()
        self.textBrowser_sim_info.append("Real-time simulation information:\n")
        self.textBrowser_eva_info.clear()
        self.textBrowser_eva_info.append("Evaluate simulation result information:\n")
        self.textBrowser_sim_info.append("%-4s %-8s  %-6s  %-32s %-56s %-52s %-7s %-4s" %
                                         ("step", "time", "sim", "flow", "speed", "queue", "delay", "act"))
        self.textBrowser_sim_info.append("*" * 176)
        # 保存仿真信息文本
        # info = "Real-time simulation information:\n" + "%-4s %-8s  %-6s  %-32s %-56s %-52s %-7s %-4s\n" % \
        #        ("step", "time", "sim", "flow", "speed", "queue", "delay", "act") + ("*" * 176) + '\n'
        # with open('./model/simulation.txt', 'a+') as f:
        #     f.write(info)
        # 保存评估信息文本
        # with open('./model/evaluate.txt', 'a+') as f:
        #     f.write("Evaluate simulation result information:\n")

    # 刷新仿真信息文本浏览框
    def update_simulation_textBrowser(self, info):
        self.textBrowser_sim_info.append(info)
        # 保存仿真信息文本
        # with open('./model/simulation.txt', 'a+') as f:
        #     f.write(info + '\n')
        QApplication.processEvents()

    # 刷新进度条
    def update_progressBar(self, info):
        self.progressBar.setValue(info)
        self.progressBar.update()

    # 保存仿真数据记录
    def save_simulation_data(self, info):
        if info:
            self.pushButton_simulation_stop_continue.setStyleSheet(self.QSS_sheet[1])
            self.pushButton_simulation_stop_continue.setText("停止仿真")
            # 保存为txt文件
            name = time.strftime("%Y-%m-%d-%H-%M-%S") + ".txt"
            path = "./result/simulation.txt"
            with open(path, "w") as f:
                f.write(self.textBrowser_sim_info.toPlainText())
            path = "./result/evaluate.txt"
            with open(path, "w") as f:
                f.write(self.textBrowser_eva_info.toPlainText())
            # 绘制延误曲线
            delay = []
            legend = ["delay"]
            with open(path, "r") as f:
                lines = f.readlines()
            for i in range(4 + 5, len(lines)):
                line = lines[i].split()[-1][1:-1]
                delay.append(float(line))
            # 绘图
            x = np.linspace(0, len(delay), len(delay))
            plt.plot(x, delay)
            # 设置坐标轴名称
            plt.xlabel("Step", fontproperties='Times New Roman', size=10.5)
            plt.ylabel("delay", fontproperties='Times New Roman', size=10.5)
            # 设置网格
            plt.grid()
            # 设置图例
            plt.legend(legend, loc="lower right", frameon=False)
            # 设置标题
            plt.title("Average delay variation", fontproperties='SimSun', size=10.5)
            # 保存图片
            plt.savefig("delay.svg")

    # 运行仿真
    def run_simulation(self):
        # 启动vissim
        command = r'RunAsDate.exe 01\01\2008 00:04:00 "%s"' % self.program_path
        os.system(command)
        # 检测vissim是否运行
        flag = process.process.detect_vissim()
        if not flag:
            reply = QMessageBox.warning(self, "警告", "请先运行Vissim 4.30 软件", QMessageBox.Yes |
                                        QMessageBox.No, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                self.waiting.show()
                try:
                    command = r'RunAsDate.exe 01\01\2008 00:04:00 "%s"' % self.program_path
                    os.system(command)
                    # start_vissim_application = threading.Thread(target=os.startfile, args=(self.program_path,))
                    # start_vissim_application.daemon = 1
                    # start_vissim_application.start()
                    while True:
                        flag = process.process.detect_vissim()
                        if flag:
                            for i in range(80000):
                                QApplication.processEvents()
                            start_flag = True
                            self.waiting.close()
                            break
                except (IndexError, Exception):
                    start_flag = False
                    self.waiting.close()
                self.waiting.close()
            else:
                start_flag = False
        else:
            start_flag = True
        if start_flag:
            if simulation.device == "cuda":
                reply = QMessageBox.information(self, "提示", "系统检测到GPU,是否选择GPU进行训练", QMessageBox.Yes |
                                                QMessageBox.No, QMessageBox.Yes)
                if reply == QMessageBox.No:
                    simulation.device = "cpu"
            self.pushButton_simulation_run.setEnabled(False)
            self.pushButton_simulation_stop_continue.setEnabled(True)
            self.pushButton_simulation_stop_continue.setStyleSheet(self.QSS_sheet[0])
            self.pushButton_simulation_run.setStyleSheet(self.QSS_sheet[1])
            # 备份已存在的网络模型文件
            backup_model('./model/', './backup/')
            os.system("xcopy .\other\draw_result.py .\model /e /y /q")
            # 显示提示信息
            self.show_hint_information()
            # 加载仿真环境参数
            self.load_environment_setting()
            # 加载仿真配时参数设置
            self.load_timing_setting()
            # 加载仿真算法参数
            self.load_algorithm_setting()
            # 加载网络模型参数设置
            self.load_network_setting()
            # 加载车流量配置文件
            self.load_traffic_flow_file()
            # 生成配时方案
            self.plans = create_plans(self.timming)
            # 启动仿真
            self.sim_task.stop_flag = False
            self.sim_task.para = [self.net_path, self.simulation, self.plans]
            self.sim_task.start()

    # 停止/继续仿真
    def stop_continue_simulation(self):
        if self.pushButton_simulation_stop_continue.text() == "停止仿真":
            self.pushButton_simulation_stop_continue.setText("继续仿真")
            self.pushButton_simulation_quit.setEnabled(True)
            self.pushButton_simulation_quit.setStyleSheet(self.QSS_sheet[0])
            if self.sim_task.handle == -1:
                return 0
            SuspendThread(self.sim_task.handle)
            message = "Stop of the Simulation"
            sp = int((178 - len(message)) / 2)
            sim_info = "\n" + " " * sp + "%s" % (str(message)) + "\n"
            self.textBrowser_sim_info.append(sim_info)
        elif self.pushButton_simulation_stop_continue.text() == "继续仿真":
            self.pushButton_simulation_stop_continue.setText("停止仿真")
            self.pushButton_simulation_quit.setEnabled(False)
            self.pushButton_simulation_quit.setStyleSheet(self.QSS_sheet[1])
            if self.sim_task.handle == -1:
                return 0
            ResumeThread(self.sim_task.handle)
            message = "Continue of the Simulation"
            sp = int((178 - len(message)) / 2)
            sim_info = "\n" + " " * sp + "%s" % (str(message)) + "\n"
            self.textBrowser_sim_info.append(sim_info)

    # 结束仿真
    def quit_simulation(self):
        # 销毁子线程服务
        ctypes.windll.kernel32.TerminateThread(self.sim_task.handle, 0)
        os.system("taskkill /F /IM vissim.exe")
        self.sim_task.stop_flag = True
        self.sim_task.stop_flag = True
        self.sim.EndInfoEmit.emit(True)
        self.pushButton_simulation_quit.setEnabled(False)
        self.pushButton_simulation_run.setEnabled(True)
        self.pushButton_simulation_stop_continue.setEnabled(False)
        self.pushButton_simulation_run.setStyleSheet(self.QSS_sheet[0])
        self.pushButton_simulation_quit.setStyleSheet(self.QSS_sheet[1])
        self.pushButton_simulation_stop_continue.setStyleSheet(self.QSS_sheet[1])
        self.pushButton_simulation_stop_continue.setText("停止仿真")
        # 重新注册线程
        self.sim_task = MyThread()
        self.sim_task.finished.connect(self.sim_task.deleteLater)
        # 连接自定义信号
        self.sim = self.sim_task.sim
        self.sim.SimInfoEmit.connect(self.update_simulation_textBrowser)
        self.sim.EvaInfoEmit.connect(self.update_evaluate_textBrowser)
        # 结束仿真
        message = "End of the Simulation"
        sp = int((178 - len(message)) / 2)
        sim_info = "\n" + " " * sp + "%s" % (str(message)) + "\n"
        self.textBrowser_sim_info.append(sim_info)

    """评估信息界面"""

    # 刷新评估信息文本浏览框
    def update_evaluate_textBrowser(self, info):
        self.textBrowser_eva_info.append(info)
        # 保存评估信息文本
        # with open('./model/evaluate.txt', 'a+') as f:
        #     f.write(info + '\n')
        QApplication.processEvents()

    # 关闭事件
    def closeEvent(self, event):
        if self.sim_task.isRunning():
            self.sim_task.quit()
            self.sim_task.terminate()
        del self.sim_task
        super(MainWindow, self).closeEvent(event)
